﻿using System;
using System.Collections.Generic;
using System.Text;

public class Truck : Vehicle
{
    private const int m_NumOfWheels = 12;
    private const int k_FuelCapacity = 210;
    private const string k_Capacity = "Please enter the capacity of the truck:";
    private const string k_IsCarryDangerGoods = "Please enter if truck carry danger goods (1. true, 2. false):";
    private const string k_MaxCarryAllowed = "Please enter the max carry allowed for truck:";
    private const int k_CarryingDangerGoods = 1;
    private const int k_NotCarryingDangerGoods = 2;
    private float? m_Capacity = null;
    private bool IsCarryDangerGoods = false;
    private float? m_MaxCarryAllowed = null;

    public Truck()
    {
        this.Engine = new FuelEngine(FuelEngine.eEngineFuelType.Soler, k_FuelCapacity);
        this.AllocateVehicleProperties();
    }

    private enum eVehiclePropertyIndex
    {
        ModelName = 1,
        WheelManufacturer,
        Capacity,
        IsCarryDangerGoods,
        MaxCarryAllowed
    }

    public new virtual string ToString()
    {
        string ResultStr = base.ToString();

        ResultStr = string.Concat(ResultStr, "Capacity: ", m_Capacity.ToString(), System.Environment.NewLine, "Is carry danger goods: ", IsCarryDangerGoods.ToString(), System.Environment.NewLine, "Maximum capacity: ", m_MaxCarryAllowed.ToString(), System.Environment.NewLine);
        return ResultStr;
    }

    protected override void AllocateVehicleProperties()
    {
        base.AllocateVehicleProperties();

        m_VehicleProperties.RemoveAt(0);
        m_NumOfProperties = 5;

        m_VehicleProperties.Add(new VehicleProperty(k_Capacity, 3, m_Capacity));
        m_VehicleProperties.Add(new VehicleProperty(k_IsCarryDangerGoods, 4, IsCarryDangerGoods));
        m_VehicleProperties.Add(new VehicleProperty(k_MaxCarryAllowed, 5, m_MaxCarryAllowed));
    }

    public override void SetVehicleProperty(VehicleProperty i_VehiclePropertyToSet)
    {
        // here we need accurate validations on i_VehiclePropertyToSet and throw exceptions for each error
        eVehiclePropertyIndex VehiclePropertyToSetIndex = (eVehiclePropertyIndex)i_VehiclePropertyToSet.VehiclePropertyIndex.Value;
        object InputVehiclePropertyValue = i_VehiclePropertyToSet.VehiclePropertyValue;

        try
        {
            switch (VehiclePropertyToSetIndex)
            {
                case eVehiclePropertyIndex.ModelName:
                    {
                        m_ModelName = InputVehiclePropertyValue.ToString();
                        break;
                    }

                case eVehiclePropertyIndex.WheelManufacturer:
                    {
                        m_WheelManufacturer = InputVehiclePropertyValue.ToString();
                        this.InitilizeWheels(m_NumOfWheels, Wheel.ePressureType.Truck, m_WheelManufacturer);
                        break;
                    }

                case eVehiclePropertyIndex.Capacity:
                    {
                        m_Capacity = float.Parse(InputVehiclePropertyValue.ToString());
                        break;
                    }

                case eVehiclePropertyIndex.IsCarryDangerGoods:
                    {
                        int IsCarryDangerGoodsInt = int.Parse(InputVehiclePropertyValue.ToString());

                        if (IsCarryDangerGoodsInt.Equals(k_CarryingDangerGoods))
                        {
                            IsCarryDangerGoods = true;
                        }
                        else if (IsCarryDangerGoodsInt.Equals(k_NotCarryingDangerGoods))
                        {
                            IsCarryDangerGoods = false;
                        }
                        else
                        {
                            throw new ValueOutOfRangeException("Invalid option chosen", k_CarryingDangerGoods, k_NotCarryingDangerGoods);
                        }

                        break;
                    }

                case eVehiclePropertyIndex.MaxCarryAllowed:
                    {
                        m_MaxCarryAllowed = float.Parse(InputVehiclePropertyValue.ToString());
                        break;
                    }
            }
        }
        catch (ArgumentException argumentException)
        {
            throw new ArgumentException("Invalid input: " + argumentException.Message);
        }
        catch (FormatException formatException)
        {
            throw new FormatException("Invalid input: " + formatException.Message);
        }
    }

    protected override void AllocateNewEngine(object i_VehiclePropertyValue)
    {
    }
}
